Subscript Operator |
The subscript operator denoted by operator[] can be implemented by any class that would like to provide access to its content by an index like arrays do. El operador de subíndice denotado por operator[] puede ser implementado por cualquier clase que le gustaría proporcionar acceso a su contenido por medio de índice como lo hacen los arreglos. |
Problem 1 |
Implement the operator[] in the MyArray class. Change the data member to a private member of the class. Use the DEBUG_ macro to check the index value on the Debug version only. Implemente el operator[] en la clase MyArray. Cambie el miembro data a un miembro privado de la clase. Use el macro DEBUG_ para checar el valor del índice en la versión de Depuración solamente. |
MyArray.h |
#pragma once class MyArray { public: MyArray(void); MyArray(int count); MyArray(const MyArray& init); //Copy Constructor ~MyArray(void); int GetCount(); bool Resize(int newSize); int CountEqual(double value); bool InserAt(int position, double value); bool DeleteAt(int position); // bool operator==(const MyArray& myArray) const; bool operator!=(const MyArray& myArray) const; MyArray& operator=(const MyArray& myArray); MyArray operator+(const MyArray& myArray) const; MyArray operator-(const MyArray& myArray) const; double& operator[](long index); // Subscript operator const double& operator[](long index) const;// Subscript operator private: double *data; // NOW DATA IS PRIVATE void Copy(const MyArray& myArray); int count; }; |
MyArray.cpp |
... double& MyArray::operator[](long index) // Subscript operator { #ifdef _DEBUG if (index<0) throw L"The subscript must be positive"; if (index>=count) throw L"The subscript was too large"; #endif return data[index]; } const double& MyArray::operator[](long index) const// Subscript operator { #ifdef _DEBUG if (index<0) throw L"The subscript must be positive"; if (index>=count) throw L"The subscript was too large"; #endif return data[index]; } |
Space.cpp |
... void Space::Window_Open(Win::Event& e) { MyArray x(3); x[0] = 5; x[1] = 10; x[2] = 15; Display(L"x", x); } void Space::Display(wchar_t * name, MyArray w) { const int count = w.GetCount(); wstring text; for(int i = 0; i < count ; i++) { //Sys::Format(text, L"%s[%d] = %g\r\n", name, i, w.data[i]); Sys::Format(text, L"%s[%d] = %g\r\n", name, i, w[i]); tbxOutput.Text += text; } } |
_DEBUG |
When a project is generated in Microsoft Visual Studio, this is executed in Debug mode, which defines _DEBUG. Once the program has been debugged, it is possible to compile it in Release mode, in this case, _DEBUG is not defined. Thus, during debugging, the operator[] in the MyArray class verifies that the provided index is valid, when the index is not correct an exception is thrown. However, when the class is used in Release mode, the operator[] does not check the indexes making the code fast. Cuando un proyecto se genera en Microsoft Visual Studio, este se ejecuta en el modo de Depuración (Debug) en el cual se define _DEBUG. Una vez que el programa se ha depurado y no existen errores, es posible compilar el programa en el modo de Release, cuando es te es el caso _DEBUG no está definido. Así, durante la depuración, la clase de MyArray el operator[] checa que los índices sean correctos o avienta una excepción cuando no lo son. Sin embargo, cuando la clase es usada en el proyecto configurado para Release, el operator[] no verifica los índices haciendo el código más rápido. |
Casting Operators |
The casting operators allow converting one object into an object of a different class when performing operations or when passing an object to a function. Los operadores de conversión permiten convertir un objeto en otro objeto de una clase diferente cuando se realizan operaciones o cuando un objeto se pasa a una función. |
Problem 2 |
One main problem of the MyText class is that it is necessary to call the Get Function to retrieve the text stored in the object. Implement the casting operator to convert the object to a: wchar_t*, const wchar_t* or a wstring variable. Un problema principal de la clase MyText es que es necesario llamar a la función Get para consultar el texto almaceno en el objeto. Implemente el operador de conversión para convertir el objeto a una variable: wchar_t*, const wchar_t* o wstring. |
MyText.h |
#pragma once class MyText { public: MyText(void); MyText(const wchar_t* text); MyText(const MyText& init); ~MyText(void); //wchar_t* Get(); // NO NEEDED ANYMORE void Set(const wchar_t* text); void MakeUpperCase(); void MakeLowerCase(); int ReplaceChar(wchar_t original_character, wchar_t new_character); int CountChar(wchar_t character); bool DeleteAt(int position); bool InsertAt(int position, wchar_t character); int DeleteChar(wchar_t character); // bool operator==(const MyText& text); bool operator!=(const MyText& text); MyText& operator=(const MyText& init); MyText& operator+=(const MyText& text); // operator const wchar_t*() const; //operator wchar_t*() const; operator wstring() const; private: void Copy(const MyText& init); wchar_t* data; }; |
MyText.cpp |
... MyText::operator const wchar_t*() const { return data; } //MyText::operator wchar_t*() const //{ // return data; //} MyText::operator wstring() const { return data; } |
Space.cpp |
... void Space::Window_Open(Win::Event& e) { MyText a = L"Hola"; // tbxOutput.Text = a.Get(); tbxOutput.Text = a; // tbxOutput.Text = (wchar_t*)a; // tbxOutput.Text += (const wchar_t*)a; } |
Tip |
When a function declaration has the const keyword after the closing parenthesis of the function (like the casting operators of the previous problem), this implies that the function does not change any of the member variables of the class, that is, the object remains constant after calling the function. Cuando una declaración de una función tiene la palabra clave const después de cerrar el paréntesis de la función (como en el operador de casteo del problema anterior), esto implica que la función no cambia las variables miembro de la clase, esto es, el objeto permanece constante después de llamar la función. |
Object array initialization |
It is possible to initialize an array of object using an argument list as shown, as long as the class has the respective constructor. Es posible inicializar un arreglo de objetos usando una lista de argumentos como se muestra, siempre y cuando la clase tenga el constructor respectivo. |
LanguageInfo.h |
class LanguageInfo { public: LanguageInfo(); LanguageInfo(int id, const wchar_t* name); ~LanguageInfo(); int id; wstring name; }; |
Program.h |
LanguageInfo languageInfo[]{{5, L"Español"},{6, L"Inglés"}}; |
operator() |
The function call operator() can be used to pass one, two or any number of parameter to an object using the operator() as shown in the example. El operator() de llamada de una función puede ser usado para pasar uno, dos o cualquier número de parámetros a un objeto usando el operator() como se muestra en el ejemplo. |
Problem 3 |
Create a Dialog Application called Farm. After creating the project, add a new C++ class called Camera. Cree una Aplicación de Diálogo llamada Farm. Después de crear el proyecto, agregué una nueva clase C++ llamada Camera. |
Camera.h |
#pragma once class Camera { public: Camera(); ~Camera(); double operator()(double a); double operator()(double x, double y); }; |
Camera.cpp |
#include "stdafx.h" #include "Camera.h" Camera::Camera() { } Camera::~Camera() { } double Camera::operator()(double a) { return 2.0*a; } double Camera::operator()(double x, double y) { return x+y; } |
Farm.h |
#pragma once //______________________________________ Farm.h #include "Resource.h" #include "Camera.h" class Farm: public Win::Dialog { . . . }; |
Farm.cpp |
. . . void Farm::Window_Open(Win::Event& e) { Camera c; double p = c(3.0); double q = c(5.0, 6.0); wchar_t text[32]; _snwprintf_s(text, 32, _TRUNCATE, L"%g\r\n%g", p, q); this->MessageBox(text, L"Farm", MB_OK); } |